package org.jupiter.blog.authentic.config;

import org.jupiter.blog.authentic.handler.LoginFailureHandler;
import org.jupiter.blog.authentic.handler.LoginSuccessHandler;
import org.jupiter.blog.authentic.handler.RedisAuthorizationManager;
import org.jupiter.blog.authentic.handler.JwtAuthenticationFilter;
import org.jupiter.blog.authentic.handler.RsaPasswordAuthenticationProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

	@Autowired
	private LoginSuccessHandler loginSuccessHandler;

	@Autowired
	private LoginFailureHandler loginFailureHandler;

	@Autowired
	private JwtAuthenticationFilter jwtAuthenticationFilter;

	@Autowired
	private RsaPasswordAuthenticationProvider rsaPasswordAuthenticationProvider;

	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http,
                                                       org.springframework.security.core.userdetails.UserDetailsService userDetailsService,
                                                       PasswordEncoder passwordEncoder) throws Exception {
        AuthenticationManagerBuilder builder = http.getSharedObject(AuthenticationManagerBuilder.class);
        // Ensure our RSA provider is used for username/password auth (handles frontend RSA-encrypted password)
        builder.authenticationProvider(rsaPasswordAuthenticationProvider);
        // Optionally keep DaoAuthenticationProvider for other flows (order matters; RSA first)
        builder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
        return builder.build();
    }

	@Bean
	public DaoAuthenticationProvider daoAuthenticationProvider(
			org.springframework.security.core.userdetails.UserDetailsService userDetailsService,
			PasswordEncoder passwordEncoder) {
		DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
		provider.setUserDetailsService(userDetailsService);
		provider.setPasswordEncoder(passwordEncoder);
		return provider;
	}

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http, RedisAuthorizationManager redisAuthorizationManager)
			throws Exception {
		http.csrf(AbstractHttpConfigurer::disable);
		http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
		http.authorizeHttpRequests(auth -> auth
					.requestMatchers("/auth/login").permitAll()
					.requestMatchers("/auth/logout").permitAll()
					.anyRequest().access(redisAuthorizationManager)  // 关键点：用自定义鉴权
			);
		// http.formLogin(form -> form
		// 		.loginProcessingUrl("/auth/login")
		// 		.usernameParameter("username")
		// 		.passwordParameter("password")
		// 		.successHandler(loginSuccessHandler)
		// 		.failureHandler(loginFailureHandler)
		// );
		// http.exceptionHandling(ex -> ex
		// 		.authenticationEntryPoint(new CustomAuthenticationEntryPoint())
		// 		.accessDeniedHandler(new CustomAccessDeniedHandler())
		// );

		http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
		http.authenticationProvider(rsaPasswordAuthenticationProvider);

		return http.build();
	}

	// @Bean
	// public SecurityFilterChain devFilterChain(HttpSecurity http) throws Exception {
	// 	http.csrf(AbstractHttpConfigurer::disable)  // 改成新写法
	// 			.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
	// 			.authorizeHttpRequests(auth -> auth.anyRequest().permitAll());
	// 	return http.build();
	// }

}
